home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / mtools.lha / mtools-2.0.7 / subdir.c < prev   
C/C++ Source or Header  |  1992-09-10  |  2KB  |  110 lines

  1. #include <stdio.h>
  2. #include "msdos.h"
  3.  
  4. extern int dir_entries;
  5. static int descend();
  6.  
  7. /*
  8.  * Descends the directory tree.  Returns 1 on error.  Attempts to optimize by
  9.  * remembering the last path it parsed
  10.  */
  11.  
  12. int
  13. subdir(drive, pathname)
  14. char drive;
  15. char *pathname;
  16. {
  17.     char *s, *tmp, tbuf[MAX_PATH], *path, *strcpy();
  18.     static char last_drive, lastpath[MAX_PATH];
  19.     int code;
  20.     void reset_chain();
  21.  
  22.     strcpy(tbuf, pathname);
  23.                     /* if paths are same, do nothing */
  24.     if (!strcmp(tbuf, lastpath) && last_drive == drive)
  25.         return(0);
  26.                     /* start at root */
  27.     reset_chain(OLD);
  28.     strcpy(lastpath, tbuf);
  29.     last_drive = drive;
  30.                     /* separate the parts */
  31.     tmp = &tbuf[1];
  32.     for (s = tmp; *s; ++s) {
  33.         if (*s == '/') {
  34.             path = tmp;
  35.             *s = '\0';
  36.             if (descend(path))
  37.                 return(1);
  38.             tmp = s + 1;
  39.         }
  40.     }
  41.     code = descend(tmp);
  42.     return(code);
  43. }
  44.  
  45. /*
  46.  * Find the directory and load a new dir_chain[].  A null directory
  47.  * is ok.  Returns a 1 on error.
  48.  */
  49.  
  50. static int
  51. descend(path)
  52. char *path;
  53. {
  54.     int entry;
  55.     unsigned int start;
  56.     char *newname, *unix_name();
  57.     struct directory *dir, *dir_read();
  58.     void reset_chain();
  59.                     /* nothing required */
  60.     if (*path == '\0')
  61.         return(0);
  62.  
  63.     for (entry = 0; entry < dir_entries; entry++) {
  64.         dir = dir_read(entry);
  65.                     /* if empty */
  66.         if (dir->name[0] == 0x0)
  67.             break;
  68.                     /* if erased */
  69.         if (dir->name[0] == 0xe5)
  70.             continue;
  71.                     /* skip if not a directory */
  72.         if (!(dir->attr & 0x10))
  73.             continue;
  74.  
  75.         newname = unix_name(dir->name, dir->ext);
  76.  
  77.         /*
  78.          * Be careful not to match '.' and '..' with wildcards
  79.          */
  80.         if (*newname == '.' && *path != '.')
  81.             continue;
  82.  
  83.         if (match(newname, path)) {
  84.             start = dir->start[1] * 0x100 + dir->start[0];
  85.  
  86.                     /* if '..' points to root */
  87.             if (!start && !strcmp(path, "..")) {
  88.                 reset_chain(OLD);
  89.                 return(0);
  90.             }
  91.                     /* fill in the directory chain */
  92.             if (fill_chain(start))
  93.                 return(1);
  94.  
  95.             return(0);
  96.         }
  97.     }
  98.  
  99.     /*
  100.      * If path is '.' or '..', but they weren't found, then you must be
  101.      * at root.
  102.      */
  103.     if (!strcmp(path, ".") || !strcmp(path, "..")) {
  104.         reset_chain(OLD);
  105.         return(0);
  106.     }
  107.     fprintf(stderr, "Path component \"%s\" is not a directory\n", path);
  108.     return(1);
  109. }
  110.